From: Keir Fraser Date: Fri, 30 Sep 2011 20:15:21 +0000 (+0100) Subject: x86,irq: Clean up __clear_irq_vector X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~9840 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=3a5a642a938cafc3e9eebd975b223e14610416e2;p=xen.git x86,irq: Clean up __clear_irq_vector Fix and clean up the logic to __clear_irq_vector(). We always need to clear the things related to cfg->vector. If the IRQ is currently in motion, then we need to also clear out things related to cfg->old_vector. This patch reorganizes the function to make the parallels between the two clean-ups more obvious. The main functional change here is with cfg->used_vectors; make sure to clear cfg->vector always (even if !cfg->move_in_progress); if cfg->move_in_progress, clear cfg->old_vector as well. Signed-off-by: George Dunlap Acked-by: Andrew Cooper --- diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index e0b2d01379..75041049bf 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -211,43 +211,57 @@ static void dynamic_irq_cleanup(unsigned int irq) static void __clear_irq_vector(int irq) { - int cpu, vector; + int cpu, vector, old_vector; cpumask_t tmp_mask; struct irq_cfg *cfg = irq_cfg(irq); BUG_ON(!cfg->vector); + /* Always clear cfg->vector */ vector = cfg->vector; cpus_and(tmp_mask, cfg->cpu_mask, cpu_online_map); - trace_irq_mask(TRC_HW_IRQ_CLEAR_VECTOR, irq, vector, &tmp_mask); - - for_each_cpu_mask(cpu, tmp_mask) + for_each_cpu_mask(cpu, tmp_mask) { + ASSERT( per_cpu(vector_irq, cpu)[vector] == irq ); per_cpu(vector_irq, cpu)[vector] = -1; + } cfg->vector = IRQ_VECTOR_UNASSIGNED; cpus_clear(cfg->cpu_mask); + + if ( cfg->used_vectors ) + { + ASSERT(test_bit(vector, cfg->used_vectors)); + clear_bit(vector, cfg->used_vectors); + } + cfg->used = IRQ_UNUSED; + trace_irq_mask(TRC_HW_IRQ_CLEAR_VECTOR, irq, vector, &tmp_mask); + if (likely(!cfg->move_in_progress)) return; + /* If we were in motion, also clear cfg->old_vector */ + old_vector = cfg->old_vector; cpus_and(tmp_mask, cfg->old_cpu_mask, cpu_online_map); + for_each_cpu_mask(cpu, tmp_mask) { - ASSERT( per_cpu(vector_irq, cpu)[cfg->old_vector] == irq ); - TRACE_3D(TRC_HW_IRQ_MOVE_FINISH, irq, vector, cpu); - per_cpu(vector_irq, cpu)[cfg->old_vector] = -1; + ASSERT( per_cpu(vector_irq, cpu)[old_vector] == irq ); + TRACE_3D(TRC_HW_IRQ_MOVE_FINISH, irq, old_vector, cpu); + per_cpu(vector_irq, cpu)[old_vector] = -1; } + cfg->old_vector = IRQ_VECTOR_UNASSIGNED; + cpus_clear(cfg->old_cpu_mask); + if ( cfg->used_vectors ) { - ASSERT(test_bit(vector, cfg->used_vectors)); - clear_bit(vector, cfg->used_vectors); + ASSERT(test_bit(old_vector, cfg->used_vectors)); + clear_bit(old_vector, cfg->used_vectors); } cfg->move_in_progress = 0; - cfg->old_vector = IRQ_VECTOR_UNASSIGNED; - cpus_clear(cfg->old_cpu_mask); } void clear_irq_vector(int irq)